package com.zxjbyte.yiyi.framework.common.core;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 * 基础参数类
 *
 * 建造者设计模式实现基类
 * @Author zhangxingjia
 * @Date 2023/11/9 17:47
 * @Version: 1.0
 */
public abstract class BaseArgs {

    public abstract static class Builder<B extends Builder<B, A>, A extends BaseArgs> {

        protected List<Consumer<A>> operations;

        protected abstract void validate(A args);

        public Builder() {
            this.operations = new ArrayList<>();
        }

        public A build() throws IllegalArgumentException {
            A args = newInstance();
            operations.forEach(operation -> operation.accept(args));
            validate(args);
            return args;
        }

        @SuppressWarnings("unchecked")
        private A newInstance() {
            try {
                // 获取当前类的外部类的所有构造函数列表
                for (Constructor<?> constructor :
                        this.getClass().getEnclosingClass().getDeclaredConstructors()) {
                    // 根据无参构造函数创建对象实例
                    if (constructor.getParameterCount() == 0) {
                        return (A) constructor.newInstance();
                    }
                }
                throw new RuntimeException(
                        this.getClass().getEnclosingClass() + " must have no argument constructor");
            } catch (InstantiationException
                    | IllegalAccessException
                    | InvocationTargetException
                    | SecurityException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
